<template>
  <view class="chat-layout">
    <view
      class="chat-layout__top"
    >
      <slot name="top"></slot>
    </view>
    <scroll-view
      class="chat-layout__scroll"
      scroll-y
      :upper-threshold="0"
      :scroll-top="scrollTop"
      @scrolltoupper="onScrollToUpper"
      @scroll="onScroll"
    >
      <view
        v-if="inUpperLoading && !end"
        class="chat-layout__scroll-loading"
      >
        加载中
      </view>
      <slot></slot>
    </scroll-view>
    <view
      class="chat-layout__bottom"
    >
      <slot name="bottom"></slot>
    </view>
  </view>
</template>

<script>
  import { throttle } from 'lodash'
  export default {
    props: {
      end: {}
    },
    data () {
      return {
        inUpperLoading: false,
        disableUpperLoading: false,
        scrollTop: 0
      }
    },
    async mounted () {
      await this.$next()
      this.scrollToBottom()
    },
    methods: {
      onScroll (e) {
        if (e.target.scrollTop <= 50 && (e.touches.length > 0 || e.target.deltaY >= 0) && !this.inUpperLoading && !this.disableUpperLoading) {
          this.onScrollToUpper()
        }
      },
      onScrollToUpper: throttle(async function() {
        if (this.inUpperLoading || this.disableUpperLoading || this.end) {
          return
        }
        this.inUpperLoading = true
        let oldView = await this.$utils.query(this, '.chat-layout__scroll')
        this.$emit('upper-loading', async isEnd => {
          if (isEnd) {
            this.disableUpperLoading = true
          }
          await this.$next()
          this.inUpperLoading = false
          await this.$next()
          let newView = await this.$utils.query(this, '.chat-layout__scroll')
          let obsHeight = oldView.scrollTop < 0 ? 0 : oldView.scrollTop
          this.scrollTop = newView.scrollHeight - oldView.scrollHeight + obsHeight - 100 + new Date().getTime() / 10000000000000
        })
      }, 200, {
        leading: true,
        trailing: false
      }),
      async scrollToBottom () {
        await this.$next()
        this.$utils.delay(100)
        let view = await this.$utils.query(this, '.chat-layout__scroll')
        this.scrollTop = view.scrollHeight
      }
    }
  }
</script>

<style lang="scss" scoped>
  @import "./common";
  .chat-layout {
    @extend .flex;
    @extend .flex-column;
    position: relative;
    background-color: #EFEFEF;
    & > * {
      width: 100%;
    }
    .chat-layout__scroll {
      @extend .flex-grow;
      width: 100%;
      height: 0;
      .chat-layout__scroll-loading {
        color: $c-mark-deep;
        line-height: 50px;
        text-align: center;
      }
    }
    .chat-layout__top,
    .chat-layout__bottom {
      @extend .flex-shrink;
    }
  }
</style>
